#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <pthread.h>
#define BUFFER 128 
#define PERM S_IRUSR|S_IWUSR
void* send_thread(void*);
void* recv_thread(void*);

typedef struct _stMsg {
  long lType;
  char szBuf[BUFFER + 1]; 
}TMsg;
pthread_mutex_t mutex_send = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_recv = PTHREAD_MUTEX_INITIALIZER;
unsigned int send_count = 0;
unsigned int recv_count = 0;

int main(int argc ,char* argv[]) {
  pthread_t t_send[10], t_recv[10];
  int i = 0;
  for(; i<10; i++) {
    pthread_create(&t_recv[i], NULL, recv_thread, NULL);
    pthread_create(&t_send[i], NULL, send_thread, NULL);
  }

  pthread_join(t_send[0],NULL);
  return 0;
}

void* send_thread(void* in_pv)
{
  printf("send thread start[%08x]\n", (int)pthread_self());
  int msqid = msgget(10000, PERM | IPC_CREAT);
  TMsg t_msg;
  memset(&t_msg, 0x00, sizeof(TMsg));
  t_msg.lType = 1;
  snprintf(t_msg.szBuf, BUFFER, "%s", "message");
  while(1)
  {
    msgsnd(msqid, &t_msg, sizeof(TMsg), 0);
#if 0
    pthread_mutex_lock(&mutex_send);
    send_count++;
    if(send_count % 1000000 == 0)
    {
      time_t s = time(NULL);
      printf(">>>>>[%ld][%u]\n",s , send_count);
    }
    pthread_mutex_unlock(&mutex_send);
#endif
  }
  printf("send thread end[%08x]\n", (int)pthread_self());
  return NULL;
}

void* recv_thread(void* in_pv)
{
  printf("recv thread start[%08x]\n", (int)pthread_self());
  int msqid = msgget(10000, PERM | IPC_CREAT);
  unsigned int i = 0;
  time_t s = time(NULL);
  char buf[1024];
  printf("start[%ld]\n",s);
  while(1)
  {
    msgrcv(msqid, buf, sizeof(TMsg), 1, 0);
    pthread_mutex_lock(&mutex_recv);
    recv_count++;
    if(recv_count % 1000000 == 0)
    {
      s = time(NULL);
      printf("recv:time[%ld]count[%u] thread[%08x]\n",s , recv_count, (int)pthread_self());
    }
    pthread_mutex_unlock(&mutex_recv);
  }
  printf("recv thread end[%08x]\n", (int)pthread_self());
  return NULL;
}
